<?php
// 开启严格模式
declare(strict_types=1);

namespace app\home\controller;

// 引用tp的基础控制器
use app\BaseController;
use app\common\model\Post\Cate as CateModel;
use app\common\validate\User\User as UserValiDate;
// 引入tp的视图门面
use think\facade\View;
// 引用验证码类
use think\captcha\facade\Captcha;
use think\facade\Db;
use app\common\model\User\User as UserModel;
use app\common\model\Post\Post as PostModel;
use app\common\model\User\Record as RecordModel;
use app\common\model\Post\Comment as CommentModel;
use app\common\validate\User\Record as RecordValiDate;
use think\exception\ValidateException;


class Index extends BaseController
{
    protected $middleware = [
        // except => 设置哪个方法不走中间件
        \app\home\middleware\LoginAuth::class => ['except'     => ['index', 'login', 'register', 'vercode']],
    ];
    public function initialize()
    {
        parent::initialize();
        $this->UserModel = new UserModel();
        $this->RecordModel = new RecordModel();

        // 获取cookie
        $LoginUser = !empty(cookie('LoginUser')) ? json_decode(cookie('LoginUser'), true) : [];


        $userid = isset($LoginUser['id']) ? $LoginUser['id'] : 0;

        // 查询该用户是否存在数据库
        $user = $this->UserModel::find($userid);

        $data = [
            'id' =>  isset($user['id']) ? $user['id'] : '',
            'email' => isset($user['email']) ? $user['email'] : '',
            'nickname' => isset($user['nickname']) ? $user['nickname'] : '',
            'avatar' => isset($user['avatar']) ? $user['avatar'] : '',
            'sex' => isset($user['sex']) ? $user['sex'] : '',
            'province' => isset($user['province']) ? $user['province'] : '',
            'city' => isset($user['city']) ? $user['city'] : '',
            'district' => isset($user['district']) ? $user['district'] : '',
            'content' => isset($user['content']) ? $user['content'] : '',
            'point' => isset($user['point']) ? $user['point'] : '',
            'vip' => isset($user['vip']) ? $user['vip'] : '',
            'auth' => isset($user['auth']) ? $user['auth'] : '',
            'cover' => isset($user['cover']) ? $user['cover'] : '',
            'createtime' => isset($user['createtime']) ? $user['createtime'] : '',
            'sign' => isset($user['sign']) ? $user['sign'] : ''
        ];
        $User = array_filter($data) ? $data : [];

        // 赋值给所有使用该中间件的视图
        if ($User) {
            View::assign([
                'LoginUser' => $data
            ]);
        } else {
            View::assign([
                'LoginUser' => []
            ]);
        }

        $this->LoginUser = $data;
    }

    public function index()
    {
        //接收分类导航id
        $cateid = $this->request->param('cateid', 0);
        // 置顶精华热门常规
        $state = $this->request->param('state', '');
        // 是否采纳
        $accept = $this->request->param('accept');
        // 搜索框内容
        $keyword = $this->request->param('keyword', '');
        // 定义条件数组
        $where = [];
        // 组装分类查询条件
        if ($cateid) {
            $where[] = ['cateid', '=', $cateid];
        }
        if ($state || $state == '0') {
            $where[] = ['state', '=', $state];
        }
        if ($accept === '0' || $accept == 1) {
            if ($accept) {
                $where[] = ['accept', 'exp', Db::raw('IS NOT NULL')];
            } else {
                $where[] = ['accept', 'exp', Db::raw('IS NULL')];
            }
        }
        // 搜索框模糊查询
        if ($keyword) {
            $where[] = ['title|content', 'like', "%$keyword%"];
        }

        //查询所有数据 按权重排序，降序 最多显示6个
        $CateList = CateModel::order('weigh', 'desc')->limit(6)->select();
        // 查询帖子数据
        $PostList = PostModel::with(['user'])->where($where)->order('createtime', 'desc')->paginate(['list_rows' => 7, 'query' => $this->request->param()]);
        /* 
            每次签到成功都会自动新增一条消费记录

            每天 00：00 到 23：59

            查询消费记录是否有当前登录用户签到记录
        */
        // 查询当前用户的id
        $userid = isset($this->LoginUser['id']) ? $this->LoginUser['id'] : 0;
        // 查询当前用户当天是否有签到记录
        $sign = RecordModel::whereDay('createtime')->where('userid', $userid)->where('state', 4)->find();
        // 查询签到赠送多少积分
        $SignPoint = Db::name('config')->where('key', 'SignPoint')->value('value');
        // 本周热议
        $Postlist = PostModel::whereWeek('createtime')->limit(10)->select()->order('comment_count', 'desc');
        // 回帖周榜
        $CommentWeek = CommentModel::withJoin(['user'], 'left')->field('count(*) as num,user.nickname,user.id,user.avatar')->whereWeek('comment.createtime')->group('userid')->order(['num' => 'desc'])->limit(10)->select();
        // halt($CommentWeek);
        /* 
            第一个参数 指定访问视图
            第二个参数 把控制器的变量赋值视图输出
        */
        return view::fetch('', [
            'CateList' => $CateList,
            'cateid' => $cateid,
            'PostList' => $PostList,
            'state' => $state,
            'accept' => $accept,
            'keyword' => $keyword,
            'sign' => $sign,
            'SignPoint' => $SignPoint,
            'userid' => $userid,
            'Postlist' => $Postlist,
            'CommentWeek' => $CommentWeek
        ]);
    }

    // 签到
    public function sign()
    {
        if ($this->request->isAjax()) {
            $userid = $this->request->param('userid');
            $User = $this->UserModel->find($userid);
            
            if (!$User) {
                $this->error('非法登录！');
            }
            $sign = RecordModel::where(['userid' => $userid, 'state' => 4])->whereDay('createtime')->find();
            if ($sign) {
                $this->error('你已签到，无需重复签到');
            }
            // 查询昨天是否签到
            // whereDay('create_time', 'yesterday')
            $yesterday = RecordModel::where(['userid' => $userid, 'state' => 4])->whereDay('createtime', 'yesterday')->find();
            if (!$yesterday) {
                $result=UserModel::where(['id' => $userid])->update(['sign' => 0]);
                if($result===false){
                    $this->error('更新连续签到天数失败');
                }
            }
            // 获取签到积分
            $SignPoint = Db::name('config')->where('key', 'SignPoint')->value('value');
            /* 
                消费记录 新增签到
                用户 更新积分
            */
            UserModel::startTrans();
            RecordModel::startTrans();
            // 封装消费记录的数据
            $RecordData = [
                'content' => "您签到成功，获得了{$SignPoint}积分",
                'point' => $SignPoint,
                'state' => 4,
                'userid' => $userid
            ];
            try {
                validate(RecordValiDate::class)->check($RecordData);
            } catch (ValidateException $e) {
                $this->error($e->getMessage());
            }
            $RecordStatus = $this->RecordModel->save($RecordData);
            if ($RecordStatus === FALSE) {
                $this->error('签到记录新增失败');
            }
            $user= UserModel::find($userid);
            $user->point = bcadd((string)$User['point'], (string)$SignPoint);
            
            if ($user['sign']) {
                $user->sign = $user['sign'] + 1;
            } else {
                $user->sign = 1;
            }
            $UserStatus = $user->save();

            if ($UserStatus === FALSE) {
                RecordModel::rollback();
                $this->error('用户积分更新失败');
            }

            if ($UserStatus === FALSE || $RecordStatus === FALSE) {
                RecordModel::rollback();
                UserModel::rollback();
                $this->error('签到失败');
            } else {
                RecordModel::commit();
                UserModel::commit();
                $this->success('签到成功');
            }
        }
    }

    // 登录页面
    public function login()
    {
        $LoginUser = !empty(cookie('LoginUser')) ? json_decode(cookie('LoginUser'), true) : [];
        if ($LoginUser) {
            $userid = isset($LoginUser['id']) ? $LoginUser['id'] : 0;
            $User = $this->UserModel->find($userid);
            if (!$User) {
                cookie('LoginUser', null);
                $this->error('非法登录', (string)url('/home/index/login'));
            }
            $this->success('你已登录，无须重复登录', (string)url('/home/user/index'));
        }
        if ($this->request->isPost()) {
            // 验证码 input => 全局函数 接收输入参数
            $vercode = input('vercode');
            // $vercode = request()->param('vercode');
            // 判断验证码是否正确
            if (!captcha_check($vercode)) {
                $this->error('验证码错误，请重新输入');
            }
            // 接收全部参数
            $params = $this->request->param();
            // 静态方法 条件查询 where `email` = $params['email'] find = 查询单条
            $User = UserModel::where(['email' => $params['email']])->find();
            if (!$User) {
                $this->error('用户不存在，请重新输入');
            }
            // 输入的密码拼接密码盐
            $password = md5($params['pass'] . $User['salt']);
            // 判断拼接后的密码与数据库的密码是否一致
            if ($password != $User['password']) {
                $this->error('密码错误，请重新输入');
            }
            // 封装cookie数组
            $data = [
                'id' => $User['id'],
                'email' => $User['email'],
                'nickname' => $User['nickname'],
                'avatar' => $User['avatar'],
                'sex' => $User['sex'],
                'province' => $User['province'],
                'city' => $User['city'],
                'district' => $User['district'],
                'content' => $User['content'],
                'point' => $User['point'],
                'vip' => $User['vip'],
                'auth' => $User['auth'],
                'cover' => $User['cover'],
                'createtime' => $User['createtime'],
            ];
            // 数组转为json字符串
            $json = json_encode($data);
            // cookie 助手函数
            cookie('LoginUser', $json);

            $this->success('登录成功', (string)url('/home/user/index'));
        }
        return view();
    }

    // 退出
    public function logout()
    {
        cookie('LoginUser', null);
        $this->success('退出成功', (string)url('/home/index/index'));
    }

    // 注册页面
    public function register()
    {
        $LoginUser = !empty(cookie('LoginUser')) ? json_decode(cookie('LoginUser'), true) : [];
        if ($LoginUser) {
            $userid = isset($LoginUser['id']) ? $LoginUser['id'] : 0;
            $User = $this->UserModel->find($userid);
            if (!$User) {
                cookie('LoginUser', null);
                $this->error('非法登录', (string)url('/home/index/login'));
            }
            $this->success('你已登录，无须重复登录', (string)url('/home/user/index'));
        }
        if ($this->request->isPost()) {
            // 接收验证码 接收POST类型
            // $vercode = $this->request->post('vercode','');
            // 接收验证码 接收POST GET类型
            $vercode = request()->param('vercode');
            if (!captcha_check($vercode)) {
                $this->error('验证码错误，请重新输入');
            }

            // 接收全部参数
            $params = $this->request->param();
            // 判断密码与确认密码是否一致
            if ($params['pass'] != $params['repass']) {
                $this->error('密码前后输入不一致，请重新输入');
            }
            // 生成密码盐
            $salt = build_ranstr();
            $password = md5($params['pass'] . $salt);
            // 当用户注册时，把注册积分给该用户
            $point = Db::name('config')->where('key', 'RegisterPoint')->value('value');
            // 封装数据
            $data = [
                'email' => $params['email'],
                'nickname' => $params['nickname'],
                'password' => $password,
                'salt' => $salt,
                'sex' => 0,
                'point' => $point,
                'vip' => 1,
                'auth' => 0
            ];
            // 验证数据是否正确
            try {
                // 用验证方法 第一个参数 需要验证数据 第二个 验证器
                $this->validate($data, UserValiDate::class);
            } catch (\think\exception\ValidateException $e) {
                // 把错误信息输出
                $this->error($e->getError());
            }
            // 实例化User模型
            $User = new UserModel();
            // save => 插入数据
            $result = $User->save($data);
            // 是否成功
            if ($result === false) {
                $this->error('注册失败');
            } else {
                $this->success('注册成功', (string)url('/home/index/login'));
            }
        }
        return view();
    }

    //验证邮件
    public function email()
    {
        $email = $this->request->param('email');

        $User = $this->UserModel->column('id,email,salt');
        // 定义id
        $userid = 0;
        foreach ($User as $item) {
            $Eamil = md5($item['email'] . $item['salt']);
            if ($email == $Eamil) {
                $userid = $item['id'];
                break;
            }
        }
        $user = $this->UserModel->find($userid);

        if (!$user) {
            $this->error('该邮箱不存在，请注册', (string)url('/home/index/register'));
        }

        $data = [
            'auth' => 1
        ];

        // 如果有主键就更新，没主键就是插入
        $result = $user->save($data);

        if ($result === FALSE) {
            $this->error('认证失败', (string)url('/home/index/index'));
        } else {
            $User = $this->UserModel->find($userid);
            // 封装cookie数组
            $data = [
                'id' => $User['id'],
                'email' => $User['email'],
                'nickname' => $User['nickname'],
                'avatar' => $User['avatar'],
                'sex' => $User['sex'],
                'province' => $User['province'],
                'city' => $User['city'],
                'district' => $User['district'],
                'content' => $User['content'],
                'point' => $User['point'],
                'vip' => $User['vip'],
                'auth' => $User['auth'],
                'cover' => $User['cover'],
                'createtime' => $User['createtime'],
            ];
            // 数组转为json字符串
            $json = json_encode($data);
            // cookie 助手函数
            cookie('LoginUser', $json);

            $this->success('认证成功', (string)url('/home/user/index'));
        }
    }
    // 验证码配置
    public function vercode()
    {
        return Captcha::create('vercode');
    }
}
